package com.changgou.filter;


import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 用来拦截头没有令牌的请求
 */
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    //令牌头名字
    private static final String AUTHORIZE_TOKEN = "Authorization";
    /**
     * 全局拦截
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //用户如果是登录或者一些不需要做权限认证的请求，直接放行
        String uri = request.getURI().toString();
        if (!UrlFilter.hasAuthorize(uri)){
            return chain.filter(exchange);
        }

        //获取用户令牌信息
        //1,头文件中
        String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
        //boolean true : 令牌在头文件中  false：令牌不在头文件中--》将令牌封装到头文件中，在传递给其他服务
        boolean hasToken = true;

        // 2,参数获取令牌
        if (StringUtils.isEmpty(token)){
            hasToken = false;
            token= request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
        }
        //3,Cookie 中
        if (StringUtils.isEmpty(token)){
            HttpCookie httpCookie = request.getCookies().getFirst(AUTHORIZE_TOKEN);
            if (httpCookie!=null){
                token = httpCookie.getValue();
            }
        }
        //如果没令牌则拦截
        if (StringUtils.isEmpty(token)){
            //设置没用权限状态码 401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //响应空数据
            return response.setComplete();
        }else {
            //判断当前令牌是否有前缀bearer，没有需要添加
            if (!token.startsWith("bearer") || !token.startsWith("BEARER")){
                token="bearer"+token;
            }
        }
        //如果有令牌，则校验是否有效
        /*try {
            //用了公钥私钥暂时不用校验jwt了
            //JwtUtil.parseJWT(token);

            //

        } catch (Exception e) {
            //设置没用权限状态码 401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //响应空数据
            return response.setComplete();
        }*/
        //以上注释的进行优化
        /*
        如果此时令牌为空， 则不允许访问，直接拦截，如果有令牌  或者头文件没有bearer进行处理一下，设置到头中
         */


        //如果请求头中没有，我添加在头中
        if(!hasToken){
            //将令牌封装头文件中
            request.mutate().header(AUTHORIZE_TOKEN,token);
        }

        //有效放行
        return chain.filter(exchange);
    }

    /**
     * 过滤器执行顺序
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
